import com.sun.javafx.collections.MappingChange;

import java.util.*;

public class Test {
    public static void main1(String[] args) {
        //将TreeMap对象创建好之后，在插入数据的时候就会以搜索树的形式插入数据
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("hello", 6);
        treeMap.put("abc", 4);
        treeMap.put("the", 5);
        treeMap.put(null, 78);
        System.out.println(treeMap);
//        Set<Map.Entry<String,Integer>> set = treeMap.entrySet();
//        for (Map.Entry<String,Integer> entry:set) {
//            System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());
//        }

    }

    public static void main2(String[] args) {
        Set<String> set1 = new TreeSet<>();
        set1.add("hello");
        set1.add("abc");
        set1.add("hello");
        System.out.println(set1);
    }

    public int fristUniqChar(String s) {
        int[] array = new int[26];
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            array[ch - 97]++;
        }
        for (int i = 0; i < array.length; i++) {
            if (array[s.charAt(i) - 97] == 1) {
                return i;
            }
        }
        return -1;

    }

    public static void main7(String[] args) {
        HashBuck hashBuck = new HashBuck();
        hashBuck.put(1, 11);
        hashBuck.put(2, 22);
        hashBuck.put(3, 33);
        hashBuck.put(4, 66);
        hashBuck.put(11, 111);
        hashBuck.put(3, 31);
        int val = hashBuck.get(45);
        System.out.println(val);
    }

    public static void main5(String[] args) {
        HashBuck hashBuck = new HashBuck();
        Student student1 = new Student("1245");
        System.out.println(student1.hashCode());//这里我们使用hashCode方法，将其转化为哈希码
        Student student2 = new Student("1245");
        System.out.println(student2.hashCode());

//        int key = student.hashCode();
//        hashBuck.put(key,11);
//        System.out.println(hashBuck.get(key));

    }

    public static void main8(String[] args) {

        Student student1 = new Student("1245");
        //System.out.println(student1.hashCode());//这里我们使用hashCode方法，将其转化为哈希码
        Student student2 = new Student("1245");
        //System.out.println(student2.hashCode());
        HashBuck2<Student, String> hashBuck2 = new HashBuck2<>();
        hashBuck2.put(student1, "zhangsan");
        String val = hashBuck2.get(student2);
        System.out.println(val);
    }

    //有10个数据，并且数据有重复的，去重
    public static void main10(String[] args) {
        int[] array = {1, 2, 3, 3, 2, 1, 5, 9, 6, 7};
        Set<Integer> set = new HashSet<>();
        for (int x : array) {
            set.add(x);
        }
        System.out.println(set);
    }

    //有10个数据，并且数据有重复的，找到第一个重复的数据
    public static void main9(String[] args) {
        int[] array = {1, 2, 3, 3, 2, 1, 5, 9, 6, 7};
        Set<Integer> set = new HashSet<>();
        for (int x : array) {
            if (!set.contains(x)) {
                set.add(x);
            } else {
                System.out.println(x);
                return;
            }
        }
    }

    public static void main11(String[] args) {
        int[] array = {1, 2, 3, 3, 2, 1, 5, 9, 6, 7};
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i : array) {
            if (!map.containsKey(i)) {//map中没有这个数据
                map.put(i, 1);
            } else {//map中已经存在这个数据
                int val = map.get(i);//得到当前数据的val
                map.put(i, ++val);//给当前数据的val+1
            }
        }
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (entry.getValue() > 1) {
                System.out.println("key: " + entry.getKey() + " val: " + entry.getValue());
            }

        }
    }

    public int singleNumber(int[] array) {
        Set<Integer> set = new HashSet<>();//创建一个HashSet对象
        for (int i = 0; i < array.length; i++) {//遍历数组中的元素
            if (!set.contains(array[i])) {//set对象中是否存在i下标的数据
                set.add(array[i]);//不存在，将i下标的数据放入set对象中
            } else {//如果存在，则将set对象中与i下标数据相同的数据，移出set对象
                set.remove(array[i]);
            }
        }
        for (int i = 0; i < array.length; i++) {//再遍历一遍数组
            if (!set.contains(array[i])) {//数组当中存在与set对象当中一致的数据，则将这个数据返回
                return array[i];
            }
        }
        return -1;//如果没有则返回-1
    }

    public static void main12(String[] args) {
        int[] array = {1, 1, 2, 3, 4, 4, 5, 5, 6, 6};
        Set<Integer> set = new HashSet<>();//创建一个HashSet对象
        for (int i = 0; i < array.length; i++) {//遍历数组中的元素
            if (!set.contains(array[i])) {//set对象中是否存在i下标的数据
                set.add(array[i]);//不存在，将i下标的数据放入set对象中
            } else {//如果存在，则将set对象中与i下标数据相同的数据，移出set对象
                set.remove(array[i]);
            }
        }
        System.out.println(set);
    }

    //    public HashBuck.Node copyRandomList(HashBuck.Node head){
//        Map<HashBuck.Node, HashBuck.Node> map = new HashMap<>();//定义一个HashMap的对象使用K-V模型
//        HashBuck.Node cur = head;//定义cur指向head,从头节点开始遍历链表
//        while(cur != null){//cur没有将链表遍历完，进入循环
//            HashBuck.Node node = new HashBuck.Node(cur.val);//创建新节点，用来复制原本的结点，将cur结点的值，给新节点
//            map.put(cur,node);//将cur作为key，node作为value放进map对象中。
//            cur = cur.next;//cur向后遍历
//        }
//        cur = head;//将链表遍历完成之后，回到链表的头节点位置
//        while(cur != null){
//            //get返回cur结点对应的value（新节点的地址）
//            map.get(cur).next = map.get(cur.next);//新节点的next域等于cur结点的next域地址所对应的value值
//            map.get(cur).random = map.get(cur.random);//random域同理
//            cur = cur.next;//cur向后遍历
//        }
//        return map.get(head);//返回新链表的头节点（原本链表的头节点（key）所对应的value值）
//    }
    public int numJewelsInStones(String jewels, String stones) {
        int count = 0;
        Set<Character> set = new HashSet<>();
        //遍历宝石，将宝石中的字符放入set中
        for (int i = 0; i < jewels.length(); i++) {
            char ch = jewels.charAt(i);//charAt()方法是将索引处的值返回
            set.add(ch);
        }
        //遍历石头，将石头中的字符域set中的字符进行对比，存在相同的字符+1
        for (int i = 0; i < stones.length(); i++) {
            char ch = stones.charAt(i);
            if (set.contains(i)) {
                count++;
            }
        }
        return count;//返回石头中存在的宝石个数
    }

    public static void main13(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextLine()) {
            String str1 = scan.nextLine();
            String str2 = scan.nextLine();
            func2(str1, str2);
        }
    }

    public static void func(String str1, String str2) {
        Set<Character> set = new HashSet<>();
        for (char ch : str1.toUpperCase().toCharArray()) {
            set.add(ch);
        }
        for (char ch : str2.toUpperCase().toCharArray()) {
            if (set.contains(ch)) {
                set.remove(ch);
            }
        }
        System.out.println(set);
    }

    public static void func2(String str1, String str2) {
        Set<Character> set = new HashSet<>();//先定义一个set用来存放实际输入的字符
        //toUpperCase()用来将小写字母转化位大写字母,toCharArray()用来将字符转化位字符类型的数组
        for (char ch : str2.toUpperCase().toCharArray()) {//char ch表示的意思是数组当中的元素是char类型的
            set.add(ch);//将数组元素ch中的字符放入set中
        }
        Set<Character> setBroken = new HashSet<>();//再创建一个setBroken,用来将坏了的键放入其中
        //在遍历的同时将，字符串转化为数组，并且数组当中的元素为大写
        for (char ch:str1.toUpperCase().toCharArray()){//遍历目标输入的数组
            //将目标字符串中遍历到的字符与set当中的元素进行对比，如果set中没有，则将这个字符放入setBroken对象当中，并且当setBroken当中有相同的字符时，
            if(!set.contains(ch)&&!setBroken.contains(ch)){//不会将set中没有的字符放入setBroken中
                setBroken.add(ch);
                System.out.print(ch);//每放入一个，输出一个字符
            }
        }
    }
    public static List<String> topKFrequent(String[] words,int k){
        //1、遍历数组  统计每个单词出现的频率
        Map<String,Integer> hashMap = new HashMap<>();
        for (String s:words) {
            if (hashMap.get(s) == null){//这里得到的S元素的Value值为引用类型的数据，所以不能将其于0作比较，只能于null作比较。
                hashMap.put(s,1);
            }else{
                hashMap.put(s,hashMap.get(s)+1);
            }
        }
        //建立小根堆
        PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(
                k, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                if(o1.getValue().compareTo(o2.getValue()) == 0){
                    return o2.getKey().compareTo(o1.getKey());
                }
                return o1.getValue().compareTo(o2.getValue()) ;
            }
        }
        );
        //3、遍历hashMap 把里面的数据放到小根堆
        for (Map.Entry<String,Integer> entry:hashMap.entrySet()) {
            if(minHeap.size() < k){
                minHeap.offer(entry);
            }else{
                //小根堆放满k个， 下一个entry和堆顶元素比较
                Map.Entry<String,Integer> top = minHeap.peek();
                //堆顶的频率小于当前堆entry的频率 就出对  然后入队entry
                if(top.getValue().compareTo(entry.getValue()) < 0){
                    minHeap.poll();
                    minHeap.add(entry);
                }else{
                    //频率相同的情况
                    if(top.getValue().compareTo(entry.getValue()) == 0){
                        if (top.getKey().compareTo(entry.getKey()) > 0){
                            minHeap.poll();
                            minHeap.add(entry);
                        }
                    }
                }
            }
        }
        //4、此时小根堆当中一定有了结果
        List<String> ret = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            String key = minHeap.poll().getKey();
            ret.add(key);
        }
        Collections.reverse(ret);//将ret中的结果逆置
        return ret;
    }

    public static void main(String[] args) {
        String a = "a";
        String b = "b";

    }

}
